package com.cy.dda.service.cases.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.cy.dda.comm.exception.MsgException;
import com.cy.dda.comm.utils.CommonUtils;
import com.cy.dda.comm.utils.JsonObjectMapper;
import com.cy.dda.dao.mapper.cases.CasesCustomerContactInfoMapper;
import com.cy.dda.dao.mapper.cases.CasesCustomerInfoMapper;
import com.cy.dda.dao.mapper.cases.CasesMapper;
import com.cy.dda.dao.mapper.customer.CustomerCompanyEditRecordMapper;
import com.cy.dda.dao.mapper.customer.CustomerCompanyMapper;
import com.cy.dda.dao.mapper.customer.CustomerContactMapper;
import com.cy.dda.dao.mapper.customer.CustomerLiveAddressEditRecordMapper;
import com.cy.dda.dao.mapper.customer.CustomerMapper;
import com.cy.dda.dao.mapper.customer.CustomerMobileEditRecordMapper;
import com.cy.dda.dao.mapper.customer.CustomerRiskMapper;
import com.cy.dda.dao.mapper.org.OrgMapper;
import com.cy.dda.dao.mapper.user.UserMapper;
import com.cy.dda.model.PageBean;
import com.cy.dda.model.Result;
import com.cy.dda.model.ao.cases.CasesApplyEndAO;
import com.cy.dda.model.ao.cases.CasesEditAO;
import com.cy.dda.model.ao.customer.ContactInfoEditAO;
import com.cy.dda.model.domain.cases.Cases;
import com.cy.dda.model.domain.cases.CasesCustomerContactInfo;
import com.cy.dda.model.domain.cases.CasesCustomerInfo;
import com.cy.dda.model.domain.customer.Customer;
import com.cy.dda.model.domain.customer.CustomerCompany;
import com.cy.dda.model.domain.customer.CustomerCompanyEditRecord;
import com.cy.dda.model.domain.customer.CustomerContact;
import com.cy.dda.model.domain.customer.CustomerLiveAddressEditRecord;
import com.cy.dda.model.domain.customer.CustomerMobileEditRecord;
import com.cy.dda.model.domain.customer.CustomerRisk;
import com.cy.dda.model.domain.org.Org;
import com.cy.dda.model.dto.cases.CasesImportDTO;
import com.cy.dda.model.dto.cases.DistributeCasesDTO;
import com.cy.dda.model.enums.cases.CasesEndStatus;
import com.cy.dda.model.enums.cases.CasesEndType;
import com.cy.dda.model.enums.cases.CasesStatus;
import com.cy.dda.model.enums.cases.CasesType;
import com.cy.dda.model.enums.cases.CustomerType;
import com.cy.dda.model.enums.customer.ContactType;
import com.cy.dda.model.enums.customer.CustomerRiskLevel;
import com.cy.dda.model.query.cases.CasesAdminQuery;
import com.cy.dda.model.query.cases.CasesListQuery;
import com.cy.dda.model.query.user.DistributableUserListQuery;
import com.cy.dda.model.vo.cases.CasesAdminVO;
import com.cy.dda.model.vo.cases.CasesDetailInfoAdminVO;
import com.cy.dda.model.vo.cases.CasesDetailInfoVO;
import com.cy.dda.model.vo.cases.CasesListVO;
import com.cy.dda.model.vo.cases.CasesLoanDetailInfoVO;
import com.cy.dda.model.vo.customer.CustomerContactInfoVO;
import com.cy.dda.model.vo.user.DistributableUserListVO;
import com.cy.dda.model.vo.cases.CasesDetailInfoVO.repayWay;
import com.cy.dda.service.BaseService;
import com.cy.dda.service.cases.CasesService;

import lombok.extern.slf4j.Slf4j;

/**
 * 委案service
 *
 * @author: tanyilin
 * @create: 2018年11月1日 下午2:12:33
 */
@Slf4j
@Service
public class CasesServiceImpl extends BaseService implements CasesService {

	@Autowired
	private CasesMapper casesMapper;
	@Autowired
	private CasesCustomerInfoMapper casesCustomerInfoMapper;
	@Autowired
	private CasesCustomerContactInfoMapper casesCustomerContactInfoMapper;
	@Autowired
	private CustomerMapper customerMapper;
	@Autowired
	private CustomerContactMapper customerContactMapper;
	@Autowired
	private CustomerCompanyMapper customerCompanyMapper;
	@Autowired
	private CustomerRiskMapper customerRiskMapper;
	@Autowired
	private CustomerMobileEditRecordMapper customerMobileEditRecordMapper;
	@Autowired
	private CustomerLiveAddressEditRecordMapper customerLiveAddressEditRecordMapper;
	@Autowired
	private CustomerCompanyEditRecordMapper customerCompanyEditRecordMapper;
	@Autowired
	private OrgMapper orgMapper;
	@Autowired
	private UserMapper userMapper;
	
	
	
	@Override
	public List<CasesImportDTO> getCasesImportDTO(MultipartFile multipartFile) {
		
		Workbook wb = null;
		
		try {
            if (CommonUtils.isExcel2003(multipartFile.getOriginalFilename())) {
                wb = new HSSFWorkbook(multipartFile.getInputStream());
            } else {
                wb = new XSSFWorkbook(multipartFile.getInputStream());
            }
        } catch (IOException e) {
            log.error("improtExcel error:", e);
            throw new MsgException("读取Excel文件异常");
        }
		
		List<CasesImportDTO> list = new ArrayList<>();
		//try {
		Sheet sheet = wb.getSheetAt(0);
		log.info("表格长度==============》{}", sheet.getLastRowNum());
		for(int i = 1; i <= sheet.getLastRowNum(); i++) {
			Row row = sheet.getRow(i);
			
			String batchNumber = row.getCell(0) == null ? "" : row.getCell(0).getStringCellValue();
			state(!CommonUtils.isEmpty(batchNumber), "第" + i + "行数据的批次号不可为空，请校验");
			String loanNumber = row.getCell(1) == null ? "" : row.getCell(1).getStringCellValue();
			state(!CommonUtils.isEmpty(loanNumber), "第" + i + "行数据的借据号不可为空，请校验");
			String orgName = row.getCell(2) == null ? "" : row.getCell(2).getStringCellValue();
			state(!CommonUtils.isEmpty(orgName), "第" + i + "行数据的委托机构不可为空，请校验");
			String casesTypeText = row.getCell(3) == null ? "" : row.getCell(3).getStringCellValue();
			state(!CommonUtils.isEmpty(casesTypeText), "第" + i + "行数据的委案类型不可为空，请校验");
			String uniqueId = row.getCell(4) == null ? "" : row.getCell(4).getStringCellValue();
			state(!CommonUtils.isEmpty(uniqueId), "第" + i + "行数据的外部唯一ID不可为空，请校验");
			String customerName = row.getCell(5) == null ? "" : row.getCell(5).getStringCellValue();
			state(!CommonUtils.isEmpty(customerName), "第" + i + "行数据的客户姓名不可为空，请校验");
			
			String idNo = row.getCell(6) == null ? "" : row.getCell(6).getStringCellValue();
			String city = row.getCell(7) == null ? "" : row.getCell(7).getStringCellValue();
			String CustomerTypeText = row.getCell(8) == null ? "" : row.getCell(8).getStringCellValue();
			String productName = row.getCell(9) == null ? "" : row.getCell(9).getStringCellValue();
			BigDecimal rate = row.getCell(10) == null ? BigDecimal.ZERO : new BigDecimal(row.getCell(10).getNumericCellValue()).setScale(2, RoundingMode.HALF_UP);
			
			BigDecimal loanAmount = row.getCell(11) == null ? BigDecimal.ZERO : new BigDecimal(row.getCell(11).getNumericCellValue()).setScale(2, RoundingMode.HALF_UP);
			BigDecimal loanSurplusAmount = row.getCell(12) == null ? BigDecimal.ZERO : new BigDecimal(row.getCell(12).getNumericCellValue()).setScale(2, RoundingMode.HALF_UP);
			int loanPeriods = row.getCell(13) == null ? 0 : (int) row.getCell(13).getNumericCellValue();
			Date loanDate = row.getCell(14) == null ? null : row.getCell(14).getDateCellValue();
			BigDecimal overdueAmount = row.getCell(15) == null ? BigDecimal.ZERO : new BigDecimal(row.getCell(15).getNumericCellValue()).setScale(2, RoundingMode.HALF_UP);
			
			BigDecimal overdueCapital = row.getCell(16) == null ? BigDecimal.ZERO : new BigDecimal(row.getCell(16).getNumericCellValue()).setScale(2, RoundingMode.HALF_UP);
			BigDecimal overdueInterest = row.getCell(17) == null ? BigDecimal.ZERO : new BigDecimal(row.getCell(17).getNumericCellValue()).setScale(2, RoundingMode.HALF_UP);
			BigDecimal overdueFineInterest = row.getCell(18) == null ? BigDecimal.ZERO : new BigDecimal(row.getCell(18).getNumericCellValue()).setScale(2, RoundingMode.HALF_UP);
			BigDecimal otherAmount = row.getCell(19) == null ? BigDecimal.ZERO : new BigDecimal(row.getCell(19).getNumericCellValue()).setScale(2, RoundingMode.HALF_UP);
			int overdueDays = row.getCell(20) == null ? 0 : (int) row.getCell(20).getNumericCellValue();
			
			int overduePeriod = row.getCell(21) == null ? 0 : (int) row.getCell(21).getNumericCellValue();
			Date overdueDate = row.getCell(22) == null ? null : row.getCell(22).getDateCellValue();
			Date entrustStartDate = row.getCell(23) == null ? null : row.getCell(23).getDateCellValue();
			Date entrustExpireDate = row.getCell(24) == null ? null : row.getCell(24).getDateCellValue();
			String loanBankCard = row.getCell(25) == null ? "" : row.getCell(25).getStringCellValue();
			
			String orgPublicBankCard = row.getCell(26) == null ? "" : row.getCell(26).getStringCellValue();
			String mobile = row.getCell(27) == null ? "" : row.getCell(27).getStringCellValue();
			state(!CommonUtils.isEmpty(mobile), "第" + i + "行数据的客户手机号码不可为空，请校验");
			String idAddress = row.getCell(28) == null ? "" : row.getCell(28).getStringCellValue();
			String liveAddress = row.getCell(29) == null ? "" : row.getCell(29).getStringCellValue();
			String liveType = row.getCell(30) == null ? "" : row.getCell(30).getStringCellValue();
			
			String houseAddress = row.getCell(31) == null ? "" : row.getCell(31).getStringCellValue();
			String marriageType = row.getCell(32) == null ? "" : row.getCell(32).getStringCellValue();
			int childrenNum = row.getCell(33) == null ? 0 : (int) row.getCell(33).getNumericCellValue();
			String companyName = row.getCell(34) == null ? "" : row.getCell(34).getStringCellValue();
			String companyAddress = row.getCell(35) == null ? "" : row.getCell(35).getStringCellValue();
			
			String position = row.getCell(36) == null ? "" : row.getCell(36).getStringCellValue();
			String companyPhone = row.getCell(37) == null ? "" : row.getCell(37).getStringCellValue();
			String contactInfoString = row.getCell(38) == null ? "" : row.getCell(38).getStringCellValue();
			
			
			CasesImportDTO dto = new CasesImportDTO();
			dto.setBatchNumber(batchNumber);
			dto.setLoanNumber(loanNumber);
			dto.setOrgName(orgName);
			dto.setCasesTypeText(casesTypeText);
			dto.setUniqueId(uniqueId);
			dto.setCustomerName(customerName);
			dto.setIdNo(idNo);
			dto.setCity(city);
			dto.setCustomerTypeText(CustomerTypeText);
			dto.setProductName(productName);
			dto.setRate(rate);
			dto.setLoanAmount(loanAmount);
			dto.setLoanSurplusAmount(loanSurplusAmount);
			dto.setLoanPeriods(loanPeriods);
			dto.setLoanDate(loanDate);
			dto.setOverdueAmount(overdueAmount);
			dto.setOverdueCapital(overdueCapital);
			dto.setOverdueInterest(overdueInterest);
			dto.setOverdueFineInterest(overdueFineInterest);
			dto.setOtherAmount(otherAmount);
			dto.setOverdueDays(overdueDays);
			dto.setOverduePeriod(overduePeriod);
			dto.setOverdueDate(overdueDate);
			dto.setEntrustStartDate(entrustStartDate);
			dto.setEntrustExpireDate(entrustExpireDate);
			dto.setLoanBankCard(loanBankCard);
			dto.setOrgPublicBankCard(orgPublicBankCard);
			dto.setMobile(mobile);
			dto.setIdAddress(idAddress);
			dto.setLiveAddress(liveAddress);
			dto.setLiveType(liveType);
			dto.setHouseAddress(houseAddress);
			dto.setMarriageType(marriageType);
			dto.setChildrenNum(childrenNum);
			dto.setCompanyName(companyName);
			dto.setCompanyAddress(companyAddress);
			dto.setPosition(position);
			dto.setCompanyPhone(companyPhone);
			dto.setContactInfoString(contactInfoString);
			dto.setCustomerContactList(getCustomerContactList(contactInfoString));
			dto.setCasesType(getCasesType(casesTypeText));
			dto.setCustomerType(CommonUtils.isEmpty(CustomerTypeText) ? CustomerType.NOT_HAVE : getCustomerType(CustomerTypeText));
			
			if(CasesType.MONTHLY_SUPPLY.equals(dto.getCasesType())) {
				//月供委案，检验 overdueDate 是否为空
				state(overdueDate != null, "第" + i + "行数据的月供委案必须填写逾期日期，请校验数据");
			}
			
			list.add(dto);
		}
//		} catch (Exception e) {
//			log.error("improtExcel error:", e);
//			//throw new MsgException("解析文件异常");
//		}
		
		
		return list;
	}
	
	/**
	 * 解析客户联系人字符串，得到客户联系人信息列表数组
	 * 
	 * @param contactInfoString
	 * @return
	 */
	private List<CustomerContact> getCustomerContactList(String contactInfoString) {
		
		List<CustomerContact> list = new ArrayList<>();
		
		if(!CommonUtils.isEmpty(contactInfoString)) {
			String[] contactInfos = contactInfoString.split(";");
			for(String contactInfo : contactInfos) {
				if(!CommonUtils.isEmpty(contactInfo)) {
					String[] contacts = contactInfo.split("-");
					state(contacts.length == 3, "客户联系人信息格式不正确，解析异常，请校验");
					String contactTypeText = contacts[0];
					String name = contacts[1];
					String mobile = contacts[2];
					ContactType contactType = null;
					if("配偶".equals(contactTypeText)) {
						contactType = ContactType.SPOUSE;
					}else if("亲戚".equals(contactTypeText)) {
						contactType = ContactType.RELATIVE;
					}else if("同事".equals(contactTypeText)) {
						contactType = ContactType.COLLEAGUE;
					}else if("朋友".equals(contactTypeText)) {
						contactType = ContactType.FRIEND;
					}else {
						contactType = ContactType.OTHER;
					}
					CustomerContact customerContact = new CustomerContact();
					customerContact.setContactType(contactType);
					customerContact.setName(name);
					customerContact.setMobile(mobile);
					list.add(customerContact);
				}
			}
		}
		return list;
	}

	/**
	 * 判断委案类型：月供，非月供
	 * 
	 * @param casesTypeText
	 * @return
	 */
	private CasesType getCasesType(String casesTypeText) {
		CasesType casesType = null;
		if("月供".equals(casesTypeText)) {
			casesType = CasesType.MONTHLY_SUPPLY;
		}else if("非月供".equals(casesTypeText)) {
			casesType = CasesType.NON_MONTHLY_SUPPLY;
		}else {
			casesType = CasesType.OTHER;
		}
		return casesType;
	}

	/**
	 * 解析客户类型：自雇、授薪
	 * 
	 * @param CustomerTypeText
	 * @return
	 */
	private CustomerType getCustomerType(String CustomerTypeText) {
		CustomerType customerType = null;
		if("自雇".equals(CustomerTypeText)) {
			customerType = CustomerType.SELF_EMPLOYED;
		}else if("授薪".equals(CustomerTypeText)) {
			customerType = CustomerType.SALARY;
		}else {
			state(false, "客户类型只能是：自雇、授薪；请校验");
		}
		
		return customerType;
	}
	
	@Override
	@Transactional
	public void addCases(List<CasesImportDTO> casesImportList) {
		Date time = new Date();
		for(int i = 0; i < casesImportList.size(); i++) {

			CasesImportDTO casesImportDTO = casesImportList.get(i);
			
			//校验委案导入批次号
			String batchNumber = casesImportDTO.getBatchNumber();
			state(!CommonUtils.isEmpty(batchNumber), "批次号不可为空！");
			Cases dbCases = new Cases();
			dbCases.setBatchNumber(batchNumber);
			List<Cases> dbCasesList = casesMapper.select(dbCases);
			if(i == 0) {
				state(CommonUtils.isEmpty(dbCasesList), "第" + (i + 1) + "行数据的批次号已存在，请勿重复导入数据，请校验");
			}else {
				//如果dbCasesList为空，则说明是一个新的批次号，批次号不一致则不允许导入
				state(!CommonUtils.isEmpty(dbCasesList), "第" + (i + 1) + "行数据的批次号不一致，请校验");
				//如果dbCasesList不为空，则说明不是一个新的批次号，size和下标i必然 会相等，不相等就说明该批次号不是本批次的
				int size = dbCasesList.size();
				state(size == i, "第" + (i + 1) + "行数据的批次号已存在，请勿重复导入数据，请校验");
			}
			
			// 初始化索引ID
			Long orgId = 0L;
			Long casesId = 0L;
			Long customerId = 0L;
			
			// 验证委托机构
			Org org = new Org();
			org.setName(casesImportDTO.getOrgName());
			Org dbOrg = orgMapper.selectOne(org);
			if(dbOrg == null) {
				// 如果机构不存在，则新增一个机构
				org.setCreateTime(time);
				org.setUpdateTime(time);
				orgMapper.insertSelective(org);
				//得到机构ID
				orgId = org.getId();
			}else {
				//得到机构ID
				orgId = dbOrg.getId();
			}
			
			//验证客户信息
			Customer customer = new Customer();
			customer.setUniqueId(casesImportDTO.getUniqueId());
			Customer dbCustomer = customerMapper.selectOne(customer);
			if(dbCustomer == null) {
				// 如果客户不存在，则新增一个客户
				BeanUtils.copyProperties(casesImportDTO, customer);
				customer.setName(casesImportDTO.getCustomerName());
				customer.setSex(CommonUtils.getSexByIdNo(customer.getIdNo()));
				customer.setCreateTime(time);
				customer.setUpdateTime(time);
				customerMapper.insertSelective(customer);
				// 得到客户ID
				customerId = customer.getId();
				
				//新增客户居住地址修改记录初始值
				CustomerLiveAddressEditRecord customerLiveAddressEditRecord = new CustomerLiveAddressEditRecord();
				customerLiveAddressEditRecord.setCustomerId(customerId);
				customerLiveAddressEditRecord.setLiveAddress(customer.getLiveAddress());
				customerLiveAddressEditRecord.setUserId(0L);
				customerLiveAddressEditRecord.setCreateTime(time);
				customerLiveAddressEditRecordMapper.insertSelective(customerLiveAddressEditRecord);
				
				//新增客户手机号码修改记录初始值
				CustomerMobileEditRecord customerMobileEditRecord = new CustomerMobileEditRecord();
				customerMobileEditRecord.setCustomerId(customerId);
				customerMobileEditRecord.setMobile(customer.getMobile());
				customerMobileEditRecord.setUserId(0L);
				customerMobileEditRecord.setCreateTime(time);
				customerMobileEditRecordMapper.insertSelective(customerMobileEditRecord);
				
				//新增客户单位信息
				CustomerCompany customerCompany = new CustomerCompany();
				BeanUtils.copyProperties(casesImportDTO, customerCompany);
				customerCompany.setCustomerId(customerId);
				customerCompany.setCreateTime(time);
				customerCompany.setUpdateTime(time);
				customerCompanyMapper.insertSelective(customerCompany);
				//新增客户单位信息修改记录初始值
				CustomerCompanyEditRecord customerCompanyEditRecord = new CustomerCompanyEditRecord();
				BeanUtils.copyProperties(casesImportDTO, customerCompanyEditRecord);
				customerCompanyEditRecord.setCustomerId(customerId);
				customerCompanyEditRecord.setUserId(0L);
				customerCompanyEditRecord.setCreateTime(time);
				customerCompanyEditRecordMapper.insertSelective(customerCompanyEditRecord);
				
				//新增客户风险级别信息
				CustomerRisk customerRisk = new CustomerRisk();
				customerRisk.setCustomerId(customerId);
				customerRisk.setRiskLevel(CustomerRiskLevel.GENERAL);
				customerRisk.setInertiaOverdue(false);
				customerRisk.setManyOverdue(false);
				customerRisk.setCreateTime(time);
				customerRisk.setUpdateTime(time);
				customerRiskMapper.insertSelective(customerRisk);
				
				//新增客户联系人信息
				List<CustomerContact> customerContactList = casesImportDTO.getCustomerContactList();
				if(!CommonUtils.isEmpty(customerContactList)) {
					for(CustomerContact customerContact : customerContactList) {
						customerContact.setCustomerId(customerId);
						customerContact.setCreateTime(time);
						customerContact.setUpdateTime(time);
					}
					//批量新增
					customerContactMapper.insertBatch(customerContactList);
				}	
				
			}else {
				//如果存在
				customerId = dbCustomer.getId();
				//查询客户已入库的‘月供委案’数量、‘所属机构’数量，从而更新客户的风险级别信息
				int orgCount = casesMapper.selectOrgCountByCustomerId(customerId);
				int casesCount = casesMapper.selectMonthlySupplyCasesCountByCustomerId(customerId);
				Cases tempCases = new Cases();
				tempCases.setOrgId(orgId);
				tempCases.setCustomerId(customerId);
				int tempCasesCount = casesMapper.selectCount(tempCases);
				if(tempCasesCount == 0) {
					orgCount = orgCount + 1;
				}
				if(CasesType.MONTHLY_SUPPLY.equals(casesImportDTO.getCasesType())) {
					casesCount = casesCount + 1;
				}
				CustomerRisk dbCustomerRisk = new CustomerRisk();
				dbCustomerRisk.setCustomerId(customerId);
				dbCustomerRisk = customerRiskMapper.selectOne(dbCustomerRisk);
				state(dbCustomerRisk != null, "客户的风险级别信息更新异常");
				CustomerRisk updateCustomerRisk = new CustomerRisk();
				updateCustomerRisk.setId(dbCustomerRisk.getId());
				updateCustomerRisk.setUpdateTime(time);
				if(orgCount >= 2 && casesCount >= 2) {
					//多家逾期,惯性逾期
					updateCustomerRisk.setRiskLevel(CustomerRiskLevel.HIGH);
					updateCustomerRisk.setInertiaOverdue(true);
					updateCustomerRisk.setManyOverdue(true);
					updateCustomerRisk.setRemark("多家逾期,惯性逾期");
				}else if(orgCount >= 2) {
					//多家逾期
					updateCustomerRisk.setRiskLevel(CustomerRiskLevel.MIDDLE);
					updateCustomerRisk.setManyOverdue(true);
					updateCustomerRisk.setRemark("多家逾期");
				}else if(casesCount >= 2) {
					//惯性逾期
					updateCustomerRisk.setRiskLevel(CustomerRiskLevel.MIDDLE);
					updateCustomerRisk.setInertiaOverdue(true);
					updateCustomerRisk.setRemark("惯性逾期");
				}
				customerRiskMapper.updateByPrimaryKeySelective(updateCustomerRisk);
				
			}
			
			//委案
			Cases cases = new Cases();
			BeanUtils.copyProperties(casesImportDTO, cases);
			cases.setCustomerId(customerId);
			cases.setOrgId(orgId);
			cases.setCasesStatus(CasesStatus.DISTRIBUTE_WAIT);
			cases.setCasesEndStatus(CasesEndStatus.END_WAIT);
			cases.setCasesEndType(CasesEndType.END_WAIT);
			cases.setCreateTime(time);
			cases.setUpdateTime(time);
			if(CasesType.MONTHLY_SUPPLY.equals(cases.getCasesType())) {
				cases.setOverdueDays(0);
			}
			
			casesMapper.insertSelective(cases);
			//得到casesId
			casesId = cases.getId();
			
			//新增 委案-客户-原始信息
			CasesCustomerInfo casesCustomerInfo = new CasesCustomerInfo();
			BeanUtils.copyProperties(casesImportDTO, casesCustomerInfo);
			casesCustomerInfo.setCasesId(casesId);
			casesCustomerInfo.setCustomerId(customerId);
			casesCustomerInfo.setName(casesImportDTO.getCustomerName());
			casesCustomerInfo.setSex(CommonUtils.getSexByIdNo(casesImportDTO.getIdNo()));
			casesCustomerInfo.setCreateTime(time);
			casesCustomerInfo.setUpdateTime(time);
			casesCustomerInfoMapper.insertSelective(casesCustomerInfo);
			
			//新增 委案-客户联系人-原始信息
			List<CustomerContact> customerContactList = casesImportDTO.getCustomerContactList();
			if(!CommonUtils.isEmpty(customerContactList)) {
				//构造原始联系人信息列表
				List<CasesCustomerContactInfo> casesCustomerContactInfoList = new ArrayList<>();
				for(CustomerContact customerContact : customerContactList) {
					CasesCustomerContactInfo casesCustomerContactInfo = new CasesCustomerContactInfo();
					casesCustomerContactInfo.setCasesId(casesId);
					casesCustomerContactInfo.setCustomerId(customerId);
					casesCustomerContactInfo.setContactType(customerContact.getContactType());
					casesCustomerContactInfo.setName(customerContact.getName());
					casesCustomerContactInfo.setMobile(customerContact.getMobile());
					casesCustomerContactInfo.setCreateTime(time);
					casesCustomerContactInfo.setUpdateTime(time);
					casesCustomerContactInfoList.add(casesCustomerContactInfo);
				}
				//批量新增
				casesCustomerContactInfoMapper.insertBatch(casesCustomerContactInfoList);
			}
			
		}
		
		
	}

	@Override
	@Transactional
	public Result<List<Long>> distributeCasesBatch(String casesIds) {
		
		List<Long> casesIdsList = new ArrayList<>();
		
		if(CommonUtils.isEmpty(casesIds)) {
			//如果没有选择需要分配的cases，就自己从数据库查询所有待分配的cases
			casesIdsList = casesMapper.selectUnDistributeCasesIds();
		}else {
			//如果有传选中的casesIds字符串，则解析
			String[] casesIdsArr = casesIds.split(",");
			for(String str : casesIdsArr) {
				casesIdsList.add(Long.valueOf(str));
			}
		}
		
		state(!CommonUtils.isEmpty(casesIdsList), "系统中可以进行分配的委案列表为空");
		
		//升序排序
		Collections.sort(casesIdsList);
		
		//查询所有启用的用户（催收员）
		DistributableUserListQuery query = new DistributableUserListQuery();
		query.setPage(1);
		query.setLimit(100);
		List<DistributableUserListVO> userList = userMapper.selectDistributableUserList(query);
		state(!CommonUtils.isEmpty(userList), "系统中可以进行分配的催收员列表为空");
		
		//分配'委案-用户'关系
		List<DistributeCasesDTO> distributeCasesList = new ArrayList<>();
		Date time = new Date();
		int userListSize = userList.size();
		int temp = 0;
		for(int i = 0; i < casesIdsList.size(); i++) {
			DistributeCasesDTO distributeCasesDTO = new DistributeCasesDTO();
			distributeCasesDTO.setCasesId(casesIdsList.get(i));
			distributeCasesDTO.setUserId(userList.get(i - userListSize * temp).getUserId());
			distributeCasesList.add(distributeCasesDTO);
			temp = (i + 1) / userListSize;
		}
		
//		casesIdsList.stream().forEach(casesId -> {
//			int size = userList.size();
//			//生成 [0,size) 区间的随机数,作为下标index
//			int index = new Random().nextInt(size);
//			DistributeCasesDTO distributeCasesDTO = new DistributeCasesDTO();
//			distributeCasesDTO.setCasesId(casesId);
//			distributeCasesDTO.setUserId(userList.get(index).getUserId());
//			distributeCasesList.add(distributeCasesDTO);
//		});
		log.info("需要分配的cases =====》 {}", JsonObjectMapper.toJson(distributeCasesList));
		
		//批量处理
		if(!CommonUtils.isEmpty(distributeCasesList)) {
			casesMapper.distributeCasesBatch(distributeCasesList, time);
		}
		
		return Result.success("", casesIdsList);
	}

	@Override
	@Transactional
	public void redistributionCases(Long casesId) {
		Cases dbCases = casesMapper.selectByPrimaryKey(casesId);
		state(dbCases != null, "委案数据异常");
		
		//原来的催收员用户ID
		Long dbUserId = dbCases.getUserId();
		//查询所有启用的用户（催收员）
		DistributableUserListQuery query = new DistributableUserListQuery();
		query.setPage(1);
		query.setLimit(100);
		List<DistributableUserListVO> userList = userMapper.selectDistributableUserList(query);
		//把原dbUserId可分配列表里过滤掉
		userList = userList.stream().filter(u -> !u.getUserId().equals(dbUserId)).collect(Collectors.toList());
		state(!CommonUtils.isEmpty(userList), "系统中可以进行分配的催收员列表为空");
		
//		//随机选择一个用户，不能与原用户相同
//		int size = userList.size();
//		Long userId = dbUserId;
//		while(userId.equals(dbUserId)) {
//			
//			//生成 [0,size) 区间的随机数,作为下标index
//			int index = new Random().nextInt(size);
//			userId = userList.get(index).getId();
//		}
		
		//分配'委案-用户'关系
		Date time = new Date();
		List<DistributeCasesDTO> list = new ArrayList<>();
		DistributeCasesDTO distributeCasesDTO = new DistributeCasesDTO();
		distributeCasesDTO.setCasesId(casesId);
		//分配给第一个用户
		distributeCasesDTO.setUserId(userList.get(0).getUserId());
		list.add(distributeCasesDTO);
		log.info("需要分配的cases =====》 {}", JsonObjectMapper.toJson(list));
		//批量处理
		if(!CommonUtils.isEmpty(list)) {
			casesMapper.distributeCasesBatch(list, time);
		}
	}
	
	@Override
	@Transactional
	public void appointDistributeCases(Long casesId, Long userId) {
		Date time = new Date();
		List<DistributeCasesDTO> list = new ArrayList<>();
		DistributeCasesDTO distributeCasesDTO = new DistributeCasesDTO();
		distributeCasesDTO.setCasesId(casesId);
		distributeCasesDTO.setUserId(userId);
		list.add(distributeCasesDTO);
		log.info("需要分配的cases =====》 {}", JsonObjectMapper.toJson(list));
		//批量处理
		if(!CommonUtils.isEmpty(list)) {
			casesMapper.distributeCasesBatch(list, time);
		}
	}
	
	@Override
	@Transactional
	public void acceptCases(Long casesId, Long userId) {

		//先验证该委案和用户是否匹配
		Cases cases = new Cases();
		cases.setId(casesId);
		cases.setUserId(userId);
		cases = casesMapper.selectOne(cases);
		state(cases != null, "委案数据异常");
		
		//接受委案,把委案状态更新为：进行中
		casesMapper.updateCasesStatus(casesId, CasesStatus.PROCESSING, new Date());
	}

	@Override
	public PageBean<CasesAdminVO> selectCasesAdminList(CasesAdminQuery query) {
		int total = casesMapper.selectCasesAdminListCount(query);
		List<CasesAdminVO> list = new ArrayList<>();
		if(total > 0) {
			query.startPage();
			list = casesMapper.selectCasesAdminList(query);
			list.stream().forEach(c -> {
				c.setCasesTypeText(c.getCasesType().getText());
				c.setCasesStatusText(c.getCasesStatus().getText());
				c.setCasesEndStatusText(c.getCasesEndStatus().getText());
				c.setCasesEndTypeText(c.getCasesEndType().getText());
				
				if(CasesType.MONTHLY_SUPPLY.equals(c.getCasesType())) {
					//月供委案，计算动态逾期天数
					c.setOverdueDays(CommonUtils.getOverdueDays(c.getOverdueDate()));
				}
				
			});
		}
		return new PageBean<CasesAdminVO>(list, total);
	}

	@Override
	public CasesDetailInfoAdminVO selectCasesDetailInfoAdminVO(Long casesId) {
		
		//查找委案信息
		CasesDetailInfoAdminVO modelVo = casesMapper.selectCasesDetailInfoAdminVO(casesId);
		state(modelVo != null, "委案不存在");
		Date createTime = modelVo.getCreateTime();
		
		//查找委案-客户-原始信息
		CasesCustomerInfo casesCustomerInfo = new CasesCustomerInfo();
		casesCustomerInfo.setCasesId(casesId);
		casesCustomerInfo = casesCustomerInfoMapper.selectOne(casesCustomerInfo);
		state(casesCustomerInfo != null, "委案客户个人原始信息异常");
		
		//委案-客户联系人-原始信息
		CasesCustomerContactInfo casesCustomerContactInfo = new CasesCustomerContactInfo();
		casesCustomerContactInfo.setCasesId(casesId);
		List<CasesCustomerContactInfo> contactInfos = casesCustomerContactInfoMapper.select(casesCustomerContactInfo);
		List<CustomerContactInfoVO> contactInfoList = new ArrayList<>();
		contactInfos.stream().forEach(c -> {
			CustomerContactInfoVO csesCustomerContactInfoVO = new CustomerContactInfoVO();
			csesCustomerContactInfoVO.setContactTypeText(c.getContactType().getText());
			csesCustomerContactInfoVO.setName(c.getName());
			csesCustomerContactInfoVO.setMobile(c.getMobile());
			contactInfoList.add(csesCustomerContactInfoVO);
		});
		
		//设置值
		BeanUtils.copyProperties(casesCustomerInfo, modelVo);
		modelVo.setId(casesId);
		modelVo.setCasesStatusText(modelVo.getCasesStatus().getText());
		modelVo.setCustomerName(casesCustomerInfo.getName());
		modelVo.setSexText(casesCustomerInfo.getSex().getText());
		modelVo.setCreateTime(createTime);
		modelVo.setContactInfoList(contactInfoList);
		if(CasesType.MONTHLY_SUPPLY.equals(modelVo.getCasesType())) {
			//月供委案，计算动态逾期天数
			modelVo.setOverdueDays(CommonUtils.getOverdueDays(modelVo.getOverdueDate()));
		}
		
		return modelVo;
	}

	@Override
	@Transactional
	public void toConfirmEndCases(Long casesId) {
		Date time = new Date();
		//更新委案状态、委案结束状态
		int result = 1;
		result = casesMapper.updateCasesStatus(casesId, CasesStatus.END, time);
		state(result == 1, "更新委案状态异常");
		
		result = casesMapper.updateCasesEndStatus(casesId, CasesEndStatus.CONFIRMED, time);
		state(result == 1, "更新委案结束状态异常");
	}

	@Override
	public PageBean<CasesListVO> selectCasesList(CasesListQuery query) {
		
		int total = casesMapper.selectCasesListCount(query);
		List<CasesListVO> list = new ArrayList<>();
		if(total > 0) {
			query.startPage();
			list = casesMapper.selectCasesList(query);
			list.stream().forEach(c -> {
				c.setCollectionUserName(CommonUtils.nameFormat(c.getCollectionUserName()));
				c.setCasesStatusText(c.getCasesStatus().getText());
				c.setCasesTypeText(c.getCasesType().getText());
				c.setCasesEndTypeText(c.getCasesEndType().getText());
				if(CasesType.MONTHLY_SUPPLY.equals(c.getCasesType())) {
					//月供委案，计算动态逾期天数
					c.setOverdueDays(CommonUtils.getOverdueDays(c.getOverdueDate()));
				}
			});
		}
		return new PageBean<CasesListVO>(list, total);
	}

	@Override
	public CasesDetailInfoVO selectCasesDetailInfoVO(Long casesId) {
		
		CasesDetailInfoVO casesDetailInfoVO = casesMapper.selectCasesDetailInfoVO(casesId);
		state(casesDetailInfoVO != null, "委案详情数据异常");
		
		casesDetailInfoVO.setSexText(casesDetailInfoVO.getSex().getText());
		casesDetailInfoVO.setAge(CommonUtils.getAgeByIdNo(casesDetailInfoVO.getIdNo()));
		casesDetailInfoVO.setCasesTypeText(casesDetailInfoVO.getCasesType().getText());
		if(casesDetailInfoVO.getEntrustExpireDate() != null) {
			int entrustSurplusDays = CommonUtils.diffDays(new Date(), casesDetailInfoVO.getEntrustExpireDate());
			casesDetailInfoVO.setEntrustSurplusDays(entrustSurplusDays);
		}
		
		//还款方式数组
		List<repayWay> repayWayList = new ArrayList<CasesDetailInfoVO.repayWay>();
		String loanBankCard = casesDetailInfoVO.getLoanBankCard();
		String orgPublicBankCard = casesDetailInfoVO.getOrgPublicBankCard();
		
		if(!CommonUtils.isEmpty(loanBankCard)) {
			if(loanBankCard.contains("/")) {
				String[] loanBankCardArr = loanBankCard.split("/");
				state(loanBankCardArr.length == 2, "还款方式数组构造异常");
				CasesDetailInfoVO.repayWay loanRepayWay = new CasesDetailInfoVO.repayWay();
				loanRepayWay.setName(casesDetailInfoVO.getCustomerName());
				loanRepayWay.setBankName(loanBankCardArr[0]);
				loanRepayWay.setBankCard(loanBankCardArr[1]);
				repayWayList.add(loanRepayWay);
			}
		}
		
		if(!CommonUtils.isEmpty(orgPublicBankCard)) {
			if(orgPublicBankCard.contains("/")) {
				String[] orgPublicBankCardArr = orgPublicBankCard.split("/");
				state(orgPublicBankCardArr.length == 2, "还款方式数组构造异常");
				CasesDetailInfoVO.repayWay orgPublicRepayWay = new CasesDetailInfoVO.repayWay();
				orgPublicRepayWay.setName("对公账户");
				orgPublicRepayWay.setBankName(orgPublicBankCardArr[0]);
				orgPublicRepayWay.setBankCard(orgPublicBankCardArr[1]);
				repayWayList.add(orgPublicRepayWay);
			}
		}
		
		casesDetailInfoVO.setRepayWayList(repayWayList);
		
		if(CasesType.MONTHLY_SUPPLY.equals(casesDetailInfoVO.getCasesType())) {
			//月供委案，计算动态逾期天数
			casesDetailInfoVO.setOverdueDays(CommonUtils.getOverdueDays(casesDetailInfoVO.getOverdueDate()));
		}
		
		return casesDetailInfoVO;
	}

	@Override
	public CasesLoanDetailInfoVO selectCasesLoanDetailInfoVO(Long casesId) {
		CasesLoanDetailInfoVO casesLoanDetailInfoVO = casesMapper.selectCasesLoanDetailInfoVO(casesId);
		state(casesLoanDetailInfoVO != null, "委案借款详情信息异常");
		if(CasesType.MONTHLY_SUPPLY.equals(casesLoanDetailInfoVO.getCasesType())) {
			//月供委案，计算动态逾期天数
			casesLoanDetailInfoVO.setOverdueDays(CommonUtils.getOverdueDays(casesLoanDetailInfoVO.getOverdueDate()));
		}
		return casesLoanDetailInfoVO;
	}

	@Override
	@Transactional
	public void updateCasesStatusFromEndWaitToProcessing(Long casesId) {
		
		int result = casesMapper.updateCasesStatusFromEndWaitToProcessing(casesId, new Date());
		state(result == 1, "委案退回失败");
		
	}

	@Override
	public CasesDetailInfoAdminVO selectCasesEditInfoAdmin(Long casesId) {
		
		CasesDetailInfoAdminVO resultVo = casesMapper.selectCasesEditInfoAdmin(casesId);
		state(resultVo != null, "获取委案信息异常");
		
		//客户联系人信息
		CustomerContact customerContact = new CustomerContact();
		customerContact.setCustomerId(resultVo.getCustomerId());
		List<CustomerContact> customerContactList = customerContactMapper.select(customerContact);
		List<CustomerContactInfoVO> contactInfoList = new ArrayList<>();
		customerContactList.stream().forEach(cc -> {
			CustomerContactInfoVO customerContactInfoVO = new CustomerContactInfoVO();
			BeanUtils.copyProperties(cc, customerContactInfoVO);
			customerContactInfoVO.setContactTypeText(customerContactInfoVO.getContactType().getText());
			contactInfoList.add(customerContactInfoVO);
		});
		
		//赋值
		resultVo.setContactInfoList(contactInfoList);
		
		return resultVo;
	}

	@Override
	@Transactional
	public void doEditCases(CasesEditAO editAO) {
		
		Long casesId = editAO.getCasesId();
		Long customerId = editAO.getCustomerId();
		Date time = new Date();
		
		//更新委案信息
		Cases updateCases = new Cases();
		BeanUtils.copyProperties(editAO, updateCases);
		updateCases.setId(casesId);
		updateCases.setUpdateTime(time);
		casesMapper.updateByPrimaryKeySelective(updateCases);
		
		//更新客户个人信息
		Customer dbCustomer = customerMapper.selectByPrimaryKey(customerId);
		state(dbCustomer != null, "客户不存在");
		
		Customer updateCustomer = new Customer();
		BeanUtils.copyProperties(editAO, updateCustomer);
		updateCustomer.setId(customerId);
		updateCustomer.setName(editAO.getCustomerName());
		updateCustomer.setSex(CommonUtils.getSexByIdNo(editAO.getIdNo()));
		updateCustomer.setUpdateTime(time);
		customerMapper.updateByPrimaryKeySelective(updateCustomer);
		
		//添加客户手机号码变更记录
		if(!CommonUtils.isEmpty(updateCustomer.getMobile())) {
			//如果联系方式发生变更,则记录
			if(!updateCustomer.getMobile().equals(dbCustomer.getMobile())) {
				CustomerMobileEditRecord mobileEditRecord = new CustomerMobileEditRecord();
				mobileEditRecord.setCustomerId(customerId);
				mobileEditRecord.setMobile(updateCustomer.getMobile());
				mobileEditRecord.setUserId(0L);
				mobileEditRecord.setCreateTime(time);
				customerMobileEditRecordMapper.insertSelective(mobileEditRecord);
			}
		}
		
		//添加客户居住地址变更记录
		if(!CommonUtils.isEmpty(updateCustomer.getLiveAddress())) {
			//如果居住地址发生变更,则记录
			if(!updateCustomer.getLiveAddress().equals(dbCustomer.getLiveAddress())) {
				CustomerLiveAddressEditRecord liveAddressEditRecord = new CustomerLiveAddressEditRecord();
				liveAddressEditRecord.setCustomerId(customerId);
				liveAddressEditRecord.setLiveAddress(updateCustomer.getLiveAddress());
				liveAddressEditRecord.setUserId(0L);
				liveAddressEditRecord.setCreateTime(time);
				customerLiveAddressEditRecordMapper.insertSelective(liveAddressEditRecord);
			}
		}
		
		//更新客户单位信息
		CustomerCompany dbCustomerCompany = new CustomerCompany();
		dbCustomerCompany.setCustomerId(customerId);
		dbCustomerCompany = customerCompanyMapper.selectOne(dbCustomerCompany);
		
		CustomerCompany updateCustomerCompany = new CustomerCompany();
		BeanUtils.copyProperties(editAO, updateCustomerCompany);
		updateCustomerCompany.setId(dbCustomerCompany.getId());
		updateCustomerCompany.setUpdateTime(time);
		customerCompanyMapper.updateByPrimaryKeySelective(updateCustomerCompany);
		
		//添加单位信息更新记录
		CustomerCompanyEditRecord companyEditRecord = new CustomerCompanyEditRecord();
		BeanUtils.copyProperties(editAO, companyEditRecord);
		companyEditRecord.setCustomerId(customerId);
		companyEditRecord.setUserId(0L);
		companyEditRecord.setCreateTime(time);
		customerCompanyEditRecordMapper.insertSelective(companyEditRecord);
		
		//更新客户联系人信息
		//得到最新的客户联系人信息列表
		List<ContactInfoEditAO> contactInfoList = editAO.getContactInfoList();
		List<CustomerContact> customerContactList = new ArrayList<>();
		if(!CommonUtils.isEmpty(contactInfoList)) {
			for(ContactInfoEditAO contactInfoEditAO : contactInfoList) {
				CustomerContact customerContact = new CustomerContact();
				BeanUtils.copyProperties(contactInfoEditAO, customerContact);
				customerContact.setCustomerId(customerId);
				customerContact.setCreateTime(time);
				customerContact.setUpdateTime(time);
				customerContactList.add(customerContact);
			}
			//批量新增
			customerContactMapper.insertBatch(customerContactList);
			//删除无效数据
			customerContactMapper.deleteByUpdateTime(customerId, time);
		}
		
		//更新委案-客户-原始信息表
		CasesCustomerInfo dbCasesCustomerInfo = new CasesCustomerInfo();
		dbCasesCustomerInfo.setCasesId(casesId);
		dbCasesCustomerInfo.setCustomerId(customerId);
		dbCasesCustomerInfo = casesCustomerInfoMapper.selectOne(dbCasesCustomerInfo);
		
		CasesCustomerInfo updateCasesCustomerInfo = new CasesCustomerInfo();
		BeanUtils.copyProperties(editAO, updateCasesCustomerInfo);
		updateCasesCustomerInfo.setId(dbCasesCustomerInfo.getId());
		updateCasesCustomerInfo.setName(editAO.getCustomerName());
		updateCasesCustomerInfo.setSex(CommonUtils.getSexByIdNo(editAO.getIdNo()));
		updateCasesCustomerInfo.setUpdateTime(time);
		casesCustomerInfoMapper.updateByPrimaryKeySelective(updateCasesCustomerInfo);
		
		//更新委案-客户联系人-原始信息表
		List<CasesCustomerContactInfo> casesCustomerContactInfoList = new ArrayList<>();
		if(!CommonUtils.isEmpty(contactInfoList)) {
			for(ContactInfoEditAO contactInfoEditAO : contactInfoList) {
				CasesCustomerContactInfo casesCustomerContactInfo = new CasesCustomerContactInfo();
				BeanUtils.copyProperties(contactInfoEditAO, casesCustomerContactInfo);
				casesCustomerContactInfo.setCasesId(casesId);
				casesCustomerContactInfo.setCustomerId(customerId);
				casesCustomerContactInfo.setCreateTime(time);
				casesCustomerContactInfo.setUpdateTime(time);
				casesCustomerContactInfoList.add(casesCustomerContactInfo);
			}
			//批量新增
			casesCustomerContactInfoMapper.insertBatch(casesCustomerContactInfoList);
			//删除无效数据
			casesCustomerContactInfoMapper.deleteByUpdateTime(casesId, customerId, time);
		}
		
	}

	@Override
	@Transactional
	public void applyEnd(CasesApplyEndAO casesApplyEndAO) {

		Date time = new Date();
		
		//更新委案状态、委案结束状态、委案结束类型
		int result = 1;
		result = casesMapper.updateCasesStatus(casesApplyEndAO.getCasesId(), CasesStatus.END_WAIT, time);
		state(result == 1, "更新委案状态异常");
		
		result = casesMapper.updateCasesEndStatus(casesApplyEndAO.getCasesId(), CasesEndStatus.CONFIRM_WAIT, time);
		state(result == 1, "更新委案结束状态异常");
		
		result = casesMapper.updateCasesEndType(casesApplyEndAO.getCasesId(), casesApplyEndAO.getCasesEndType(), time);
		state(result == 1, "更新委案结束类型异常");
		
	}

	

	
	
	
	
	
	
	
	
	
	
	
	
}
